home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / support / fakename.c next >
Encoding:
C/C++ Source or Header  |  1990-11-08  |  4.1 KB  |  148 lines

  1. /*
  2. ** fakemail - a SysV /bin/mail preprocessor for sendmail
  3. **
  4. ** Standard AT&T /bin/mail adds it's own From_ line specifying the
  5. ** identity of the sender (commenting out any previously existing
  6. ** From_ lines in the process).  While this behavior might be
  7. ** consistent with RFC-976, it only serves to confuse mailers such
  8. ** as mailx which use the From_ line to determine reply addresses.
  9. **
  10. ** To determine the sender identity (placed in the generated From_
  11. ** line), /bin/mail uses $LOGNAME of the user/program invoking it. 
  12. ** For local mail this is moderately acceptable (the user could fake
  13. ** the sender by changing $LOGNAME), but for use with sendmail this
  14. ** behavior is unreasonable since the invocation of /bin/mail is
  15. ** done by root.  As a result, mailx reports all external mail as
  16. ** "From root", and the actual identity of the sender is obscured.
  17. **
  18. ** `fakemail' is designed as a replacement for the sendmail local
  19. ** delivery program.  It preprocesses mail messages (read from
  20. ** stdin) and changes $LOGNAME before calling the regular /bin/mail.
  21. ** The new $LOGNAME is derived from the address portion of the From_
  22. ** line, which is found in the first line of the header.
  23. **
  24. **    From user@site Fri Jun 15 13:18:09 1990
  25. **
  26. ** If no From_ line is found, $LOGNAME defaults to the user of the
  27. ** program, as with normal /bin/mail.
  28. **
  29. ** Technically, `fakemail' could be considered a slightly better
  30. ** mechanism than direct /bin/mail since you cannot spoof the
  31. ** program by changing $LOGNAME.  An argument against this, however,
  32. ** is the fact that you *can* trick `fakemail' by supplying a bogus
  33. ** From_ line as the first line of the header.
  34. **
  35. ** To use:
  36. **
  37. **    1) Compile and install this program
  38. **        make fakemail
  39. **        cpset fakemail /usr/bin
  40. **
  41. **    2) Edit /usr/lib/sendmail.cf
  42. **        change the 'Mlocal' mailer to use /usr/bin/fakemail
  43. **
  44. **    3) Restart sendmail
  45. **        ps -eaf; kill -9 <sendmail_pid>
  46. **        /usr/lib/sendmail -bd -q30m
  47. **
  48. ** NOTE: This is simply a hack for sendmail+mailx.  Use of another
  49. ** MTA (ie, smail) or MUA (ie, Elm) would eliminate any need for this
  50. ** program.
  51. **
  52. ** --
  53. ** Bill Houle                       bhoule@se-sd.SanDiego.NCR.COM
  54. ** NCR SE-San Diego                 (619) 693-5593
  55. */
  56.  
  57. #include <stdio.h>
  58. #include <string.h>
  59.  
  60. /*#define DEBUG    "/bin/cat"        /* comment this out for installation */
  61. #define    BINMAIL    "/bin/mail"
  62. #define    TRUE    1
  63. #define    FALSE    0
  64.  
  65. char    line[255], env[255];
  66. void    exit(), perror();
  67.  
  68. void syserr(str)
  69. char *str;
  70. {
  71.     perror(str);
  72.     exit(1);
  73. }
  74.  
  75. main(argc, argv)
  76. int argc;
  77. char **argv;
  78. {
  79.     int fd[2], from_found=TRUE;
  80.  
  81.     if (gets(line) != NULL) {            /* read first line    *
  82. /
  83.         strcpy(env, "LOGNAME=");
  84.         if (strncmp(line, "From ", 5) == 0) {    /* From_ line?        *
  85. /
  86.             (void) strtok(line, " \t\n\r");    /* get address token  *
  87. /
  88.             strcat(env, strtok(NULL, " \t\n\r"));
  89.         }
  90.         else {
  91.             from_found=FALSE;        /* no From_ line      *
  92. /
  93.             strcat(env, cuserid(NULL));    /* default to user-id *
  94. /
  95.         }
  96.         (void) putenv(env);            /* change $LOGNAME    *
  97. /
  98.     }
  99.  
  100.     if (pipe(fd) < 0) syserr("pipe");        /* prepare pipe       *
  101. /
  102.     switch (fork()) {                /* fork to /bin/mail  *
  103. /
  104.     case -1:
  105.         syserr("fork to /bin/mail");
  106.     case 0:
  107.         if (close(0) < 0)            /* close stdin        *
  108. /
  109.             syserr("close child stdin");
  110.         if (dup(fd[0]) != 0)            /* stdin from pipe    *
  111. /
  112.             syserr("dup pipe to stdin");
  113.         if (close(fd[0]) < 0 || close(fd[1]) < 0)
  114.             syserr("close child pipe");
  115. #ifdef DEBUG
  116.         (void) fprintf(stderr, "[set %s and exec %s]\n", env, BINMAIL);
  117.         (void) fprintf(stderr, "Debugging through %s.\n", DEBUG);
  118.         (void) execl(DEBUG, DEBUG, 0);
  119.         (void) fprintf(stderr, "Cannot exec %s from %s.\n",
  120.           DEBUG, argv[0]);
  121.         exit(0);
  122. #else
  123.         (void) execv(BINMAIL, argv);
  124.         (void) fprintf(stderr, "Cannot exec %s from %s.\n",
  125.           BINMAIL, argv[0]);
  126.         exit(1);
  127. #endif
  128.     }
  129.  
  130.     if (close(1) < 0)                /* close stdout       *
  131. /
  132.         syserr("close parent stdout");
  133.     if (dup(fd[1]) != 1)                /* stdout to pipe     *
  134. /
  135.         syserr("dup pipe to stdout");
  136.     if (close(fd[0]) < 0 || close(fd[1]) < 0)
  137.         syserr("close parent pipe");
  138.  
  139.     if (!from_found) (void) puts(line);        /* 1st line not From_ *
  140. /
  141.     while (gets(line) != NULL)            /* send rest of msg   *
  142. /
  143.         (void) puts(line);
  144.     exit(0);
  145.     return(0);                    /* make lint happy    *
  146. /
  147. }
  148.